/**
 * 
 */
package me.myachievements.persistence;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.SessionFactory;


/**
 * @author besseym
 *
 */
public abstract class PersistenceManagerImpl <T extends PersistentObject> implements PersistenceManager<T> {
	
	private Class<T> persistentObjectClass;
	private SessionFactory sessionFactory;
	
	/**
	 * Constructor
	 * @param persistentObjectClass
	 */
	public PersistenceManagerImpl(Class<T> persistentObjectClass){
		this.persistentObjectClass = persistentObjectClass;
	}

	/*
	 * (non-Javadoc)
	 * @see me.myachievements.persistence.PersistenceManager#create(me.myachievements.persistence.PersistentObject)
	 */
	public void create(T t){
		getCurrentSession().save(t);
	}
	
	/*
	 * (non-Javadoc)
	 * @see me.myachievements.persistence.PersistenceManager#read(java.lang.Long)
	 */
	public T read(Long id){
		return (T) getCurrentSession().get(persistentObjectClass, id);
	}
	
	/*
	 * (non-Javadoc)
	 * @see me.myachievements.persistence.PersistenceManager#update(me.myachievements.persistence.PersistentObject)
	 */
	public void update(T t){
		getCurrentSession().update(t);
	}
	
	/*
	 * (non-Javadoc)
	 * @see me.myachievements.persistence.PersistenceManager#delete(me.myachievements.persistence.PersistentObject)
	 */
	public void delete(T t){
		getCurrentSession().delete(t);
	}
	
	/*
	 * (non-Javadoc)
	 * @see me.myachievements.persistence.PersistenceManager#findAll()
	 */
	public List<T> findAll() {
		Criteria criteria = getCurrentSession().createCriteria(persistentObjectClass); 
		return (List<T>) criteria.list();
	}
	
	/*
	 * (non-Javadoc)
	 * @see me.myachievements.persistence.PersistenceManager#countAll()
	 */
	public int countAll() { 
		Criteria criteria = getCurrentSession().createCriteria(persistentObjectClass);
		criteria.setProjection(Projections.rowCount()); 
		return (Integer) criteria.uniqueResult();
	}
	
	/**
	 * @return the current session
	 */
	public Session getCurrentSession() { 
		return sessionFactory.getCurrentSession(); 
	}

	/**
	 * @return the sessionFactory
	 */
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	
	/**
	 * @param sessionFactory the sessionFactory to set
	 */
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

}
